<script lang="ts" setup>
import {onMounted, reactive, ref} from 'vue'
import {useRouter} from 'vue-router'
import {Cropper} from 'vue-advanced-cropper'
import 'vue-advanced-cropper/dist/style.css'
import {handleError, success, warning} from '@/utils/message'
import {validate} from '@/utils/validate'
import {SPACE} from '@/constants/messages'
import {FolderOpenOutlined, PictureOutlined, PlusOutlined, TeamOutlined, UploadOutlined} from '@ant-design/icons-vue'
import MainLayout from '@/components/layout/MainLayout.vue'
import StorageDisplay from '@/components/common/StorageDisplay.vue'
import ProgressiveImage from '@/components/common/ProgressiveImage.vue'
import {fileApi, spaceApi} from '@/api'
import type {SpaceCreateDTO} from '@/types/dto/space'
import type {MySpaceVO} from '@/types/vo/space'
import {getRoleText} from '@/constants/space'
import {useCropper} from '@/composables/useCropper'

const router = useRouter()

const loading = ref(false)
const creating = ref(false)
const createModalVisible = ref(false)
const joining = ref(false)
const joinModalVisible = ref(false)
const mySpaces = ref<MySpaceVO | null>(null)

// 使用裁剪组合式函数
const {
  cropperModalVisible,
  cropperImageSrc,
  cropperRef,
  previewUrl: coverPreview,
  croppedFile: coverFile,
  handleFileSelect: handleCoverChange,
  zoom,
  rotate,
  flip,
  reset,
  confirm: handleCropperConfirm,
  cancel: handleCropperCancel,
  aspectRatio
} = useCropper({
  maxSize: 5,
  aspectRatio: 3, // 3:1 宽屏比例
  shape: 'rect'
})

const createForm = reactive<SpaceCreateDTO>({
  spaceName: '',
  spaceDesc: '',
  spaceType: 0,
  memberLimit: 10
})

const joinForm = reactive({
  inviteCode: ''
})

const loadMySpaces = async () => {
  loading.value = true
  try {
    mySpaces.value = await spaceApi.getMySpaces()
  } catch (error: any) {
    handleError(error, SPACE.LIST_LOAD_FAILED)
  } finally {
    loading.value = false
  }
}

const showCreateModal = () => {
  createForm.spaceName = ''
  createForm.spaceDesc = ''
  createForm.spaceType = 0
  createForm.memberLimit = 10
  coverPreview.value = ''
  coverFile.value = null
  createModalVisible.value = true
}

const showJoinModal = () => {
  joinForm.inviteCode = ''
  joinModalVisible.value = true
}

const handleCreate = async () => {
  if (!validate.required(createForm.spaceName) || !validate.length(createForm.spaceName, 2, 30)) {
    warning('请输入空间名称（2-30个字符）')
    return
  }

  creating.value = true
  try {
    let coverUrl = ''

    if (coverFile.value) {
      coverUrl = await fileApi.uploadCover(coverFile.value)
    }

    const result = await spaceApi.create({
      ...createForm,
      coverUrl: coverUrl || undefined
    })

    success(SPACE.CREATE_SUCCESS)
    createModalVisible.value = false
    router.push(`/space/${result.id}`)
  } catch (error: any) {
    handleError(error, SPACE.CREATE_FAILED)
  } finally {
    creating.value = false
  }
}

const handleJoin = async () => {
  if (!validate.required(joinForm.inviteCode)) {
    warning('请输入邀请码')
    return
  }

  joining.value = true
  try {
    const result = await spaceApi.join({
      inviteCode: joinForm.inviteCode.trim()
    })

    success(SPACE.JOIN_SUCCESS)
    joinModalVisible.value = false

    // 刷新空间列表
    await loadMySpaces()

    // 跳转到空间详情页
    router.push(`/space/${result.id}`)
  } catch (error: any) {
    handleError(error, '加入失败，请检查邀请码是否正确')
  } finally {
    joining.value = false
  }
}

// 跳转到空间详情
const goToSpace = (id: number) => {
  router.push(`/space/${id}`)
}

onMounted(() => {
  loadMySpaces()
})
</script>

<template>
  <main-layout>
    <div class="space-list-container">
      <div class="header-actions">
        <h1>我的空间</h1>
        <a-space>
          <a-button size="large" @click="showJoinModal">
            <template #icon>
              <TeamOutlined/>
            </template>
            加入空间
          </a-button>
          <a-button size="large" type="primary" @click="showCreateModal">
            <template #icon>
              <PlusOutlined/>
            </template>
            创建空间
          </a-button>
        </a-space>
      </div>

      <a-spin :spinning="loading">
        <!-- 我创建的空间 -->
        <div v-if="mySpaces" class="space-section">
          <h2>我创建的空间 ({{ mySpaces.owner.length }})</h2>
          <div v-if="mySpaces.owner.length > 0" class="space-grid">
            <div
                v-for="space in mySpaces.owner"
                :key="space.id"
                class="space-card"
                @click="goToSpace(space.id!)"
            >
              <div class="space-cover">
                <progressive-image
                    v-if="space.coverUrl"
                    :alt="space.spaceName"
                    :lazy="true"
                    :src="space.coverUrl"
                    class="cover-image"
                    fit="cover"
                />
                <div v-else class="space-cover-placeholder">
                  <FolderOpenOutlined/>
                </div>
                <div class="space-type-badge">
                  <a-tag :color="space.spaceType === 0 ? 'blue' : 'green'">
                    {{ space.spaceType === 0 ? '私有' : '团队' }}
                  </a-tag>
                </div>
              </div>
              <div class="space-info">
                <h3>{{ space.spaceName }}</h3>
                <p class="space-desc">{{ space.spaceDesc || '暂无描述' }}</p>
                <div class="space-stats">
                  <span><PictureOutlined/> {{ space.usage?.currentPictureCount || 0 }}</span>
                  <span><TeamOutlined/> {{ space.usage?.currentMemberCount || 1 }}</span>
                </div>
                <!-- 存储空间展示 -->
                <div v-if="space.maxStorageSize && space.maxStorageSize !== -1" class="space-storage">
                  <storage-display
                      :total="space.maxStorageSize"
                      :used="space.usage?.currentStorageSize || 0"
                      mode="card"
                  />
                </div>
              </div>
            </div>
          </div>
          <a-empty v-else description="还没有创建空间"/>
        </div>

        <!-- 我加入的空间 -->
        <div v-if="mySpaces" class="space-section">
          <h2>我加入的空间 ({{ mySpaces.joined.length }})</h2>
          <div v-if="mySpaces.joined.length > 0" class="space-grid">
            <div
                v-for="space in mySpaces.joined"
                :key="space.id"
                class="space-card"
                @click="goToSpace(space.id!)"
            >
              <div class="space-cover">
                <progressive-image
                    v-if="space.coverUrl"
                    :alt="space.spaceName"
                    :lazy="true"
                    :src="space.coverUrl"
                    class="cover-image"
                    fit="cover"
                />
                <div v-else class="space-cover-placeholder">
                  <FolderOpenOutlined/>
                </div>
                <div class="space-role-badge">
                  <a-tag color="purple">{{ getRoleText(space.currentUserRole) }}</a-tag>
                </div>
              </div>
              <div class="space-info">
                <h3>{{ space.spaceName }}</h3>
                <p class="space-desc">{{ space.spaceDesc || '暂无描述' }}</p>
                <div class="space-stats">
                  <span><PictureOutlined/> {{ space.usage?.currentPictureCount || 0 }}</span>
                  <span><TeamOutlined/> {{ space.usage?.currentMemberCount || 1 }}</span>
                </div>
                <!-- 存储空间展示 -->
                <div v-if="space.maxStorageSize && space.maxStorageSize !== -1" class="space-storage">
                  <storage-display
                      :total="space.maxStorageSize"
                      :used="space.usage?.currentStorageSize || 0"
                      mode="card"
                  />
                </div>
              </div>
            </div>
          </div>
          <a-empty v-else description="还没有加入其他空间"/>
        </div>
      </a-spin>

      <!-- 创建空间对话框 -->
      <a-modal
          v-model:open="createModalVisible"
          :confirm-loading="creating"
          title="创建空间"
          @ok="handleCreate"
      >
        <a-form :model="createForm" layout="vertical">
          <a-form-item label="空间名称" required>
            <a-input
                v-model:value="createForm.spaceName"
                :maxlength="30"
                placeholder="请输入空间名称（2-30字符）"
            />
          </a-form-item>
          <a-form-item label="空间描述">
            <a-textarea
                v-model:value="createForm.spaceDesc"
                :maxlength="200"
                :rows="3"
                placeholder="请输入空间描述（可选）"
            />
          </a-form-item>

          <a-form-item label="空间封面">
            <div class="cover-upload">
              <div v-if="coverPreview" class="cover-preview">
                <progressive-image :lazy="false" :src="coverPreview" alt="封面预览" fit="cover"/>
              </div>
              <div v-else class="cover-preview-placeholder">
                <FolderOpenOutlined style="font-size: 48px; color: #ccc;"/>
                <p>选择封面图片</p>
              </div>
              <a-upload
                  :before-upload="handleCoverChange"
                  :show-upload-list="false"
                  accept="image/*"
              >
                <a-button block style="margin-top: 8px;">
                  <UploadOutlined/>
                  {{ coverPreview ? '重新选择' : '选择封面' }}
                </a-button>
              </a-upload>
              <p class="upload-hint">支持 JPG、PNG、GIF、WEBP，不超过 5MB，建议 1200x400 像素</p>
            </div>
          </a-form-item>

          <a-form-item label="空间类型" required>
            <a-radio-group v-model:value="createForm.spaceType">
              <a-radio :value="0">私有空间（仅自己可见）</a-radio>
              <a-radio :value="1">团队空间（可邀请成员）</a-radio>
            </a-radio-group>
          </a-form-item>
          <a-form-item v-if="createForm.spaceType === 1" label="成员上限">
            <a-input-number
                v-model:value="createForm.memberLimit"
                :max="50"
                :min="1"
                style="width: 100%"
            />
          </a-form-item>
        </a-form>
      </a-modal>

      <!-- 加入空间对话框 -->
      <a-modal
          v-model:open="joinModalVisible"
          :confirm-loading="joining"
          title="加入空间"
          @ok="handleJoin"
      >
        <a-form :model="joinForm" layout="vertical">
          <a-form-item label="邀请码" required>
            <a-input
                v-model:value="joinForm.inviteCode"
                :maxlength="20"
                placeholder="请输入空间邀请码"
            />
          </a-form-item>
          <a-alert
              description="请向空间所有者或管理员获取邀请码，然后输入上方输入框即可加入空间"
              message="如何获取邀请码？"
              show-icon
              type="info"
          />
        </a-form>
      </a-modal>

      <!-- 封面裁剪对话框 -->
      <a-modal
          v-model:open="cropperModalVisible"
          :width="900"
          cancel-text="取消"
          ok-text="确认"
          title="调整空间封面（3:1宽屏比例）"
          @cancel="handleCropperCancel"
          @ok="handleCropperConfirm"
      >
        <div class="cropper-container">
          <cropper
              ref="cropperRef"
              :src="cropperImageSrc"
              :stencil-props="{aspectRatio}"
              class="cropper"
          />
          <div class="cropper-toolbar">
            <a-space :size="12">
              <a-button size="small" @click="zoom(1.1)">放大</a-button>
              <a-button size="small" @click="zoom(0.9)">缩小</a-button>
              <a-button size="small" @click="rotate(90)">旋转</a-button>
              <a-button size="small" @click="flip(true, false)">翻转</a-button>
              <a-button size="small" @click="reset">重置</a-button>
            </a-space>
          </div>
          <p class="cropper-hint">💡 拖动调整位置，滚轮缩放大小</p>
        </div>
      </a-modal>
    </div>
  </main-layout>
</template>

<style lang="scss" scoped>
@use '@/assets/styles/variables.scss' as *;
@use '@/assets/styles/components.scss' as *;

.space-list-container {
  @include container;
  padding: $spacing-xl $spacing-lg;

  @include responsive($breakpoint-md) {
    padding: $spacing-lg $spacing-md;
  }
}

.header-actions {
  @include flex-between;
  margin-bottom: $spacing-2xl;
  padding-bottom: $spacing-lg;
  border-bottom: 2px solid $border-light;

  h1 {
    font-size: $font-4xl;
    font-weight: $font-extrabold;
    margin: 0;
    background: $gradient-primary;
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;

    @include responsive($breakpoint-md) {
      font-size: $font-3xl;
    }
  }

  :deep(.ant-btn) {
    box-shadow: $shadow-sm;

    &:hover {
      transform: translateY(-2px);
      box-shadow: $shadow-md;
    }
  }

  :deep(.ant-btn-primary) {
    background: $gradient-primary;
    border: none;

    &:hover {
      box-shadow: $shadow-primary;
    }
  }
}

.space-section {
  margin-bottom: $spacing-3xl;

  h2 {
    font-size: $font-2xl;
    font-weight: $font-bold;
    margin-bottom: $spacing-xl;
    color: $text-primary;
    position: relative;
    padding-left: $spacing-md;

    &::before {
      content: '';
      position: absolute;
      left: 0;
      top: 50%;
      transform: translateY(-50%);
      width: 4px;
      height: 24px;
      background: $gradient-primary;
      border-radius: $radius-full;
    }
  }
}

.space-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: $spacing-xl;

  @include responsive($breakpoint-lg) {
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: $spacing-lg;
  }

  @include responsive($breakpoint-md) {
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: $spacing-md;
  }
}

.space-card {
  @include space-card;

  .space-cover {
    .cover-image {
      width: 100%;
      height: 100%;

      :deep(.progressive-image) {
        height: 100%;
        border-radius: 0;
      }

      :deep(img) {
        object-fit: cover;
      }
    }
  }

  .space-info {
    .space-storage {
      margin-top: $spacing-md;
    }
  }
}

.cover-upload {
  @include cover-upload;

  .cover-preview {
    :deep(.progressive-image) {
      height: 100%;
      border-radius: 0;
    }

    :deep(img) {
      object-fit: cover;
    }
  }
}

.cropper-container {
  @include cropper-container;
}
</style>